package com.voc.im.model;

import com.voc.im.bean.ChatEntry;
import com.voc.im.bean.ChatRecord;
import com.voc.im.bean.UserRoom;
import io.datafx.controller.injection.scopes.ApplicationScoped;
import javafx.beans.property.*;
import javafx.collections.FXCollections;

import java.util.List;
import java.util.Map;

@ApplicationScoped
public class ChatRecordModel {

    private MapProperty<Integer, ListProperty<ChatRecord>> listPropertyMap;

    private ObjectProperty<UserRoom> objectProperty;

    private ListProperty<ChatEntry> entryListProperty;

    private IntegerProperty selectedEntryIndex;

    private IntegerProperty selectedRecordIndex;

    private Map<Integer, ListProperty<ChatRecord>> listPropertyMap() {
        if (listPropertyMap == null) {
            listPropertyMap = new SimpleMapProperty<>(FXCollections.observableHashMap());
        }
        return listPropertyMap;
    }

    public Map<Integer, ListProperty<ChatRecord>> getListPropertyMap() {
        return this.listPropertyMap();
    }

    private ListProperty<ChatRecord> recordListProperty(UserRoom userRoom) {
        ListProperty<ChatRecord> listProperty = getListPropertyMap().get(userRoom.getId());
        if (listProperty == null) {
            listProperty = new SimpleListProperty<>(FXCollections.observableArrayList());
        }
        return listProperty;
    }

    public ListProperty<ChatRecord> getRecordListProperty(UserRoom userRoom) {
        return this.recordListProperty(userRoom);
    }

    private ObjectProperty<UserRoom> objectProperty() {
        if (objectProperty == null) {
            objectProperty = new SimpleObjectProperty<>();
        }
        return objectProperty;
    }

    public ObjectProperty<UserRoom> getObjectProperty() {
        return objectProperty();
    }

    private ListProperty<ChatEntry> entryListProperty() {
        if (entryListProperty == null) {
            entryListProperty = new SimpleListProperty<>(FXCollections.observableArrayList());
        }
        return entryListProperty;
    }

    public ListProperty<ChatEntry> getEntryListProperty() {
        return this.entryListProperty();
    }

    private IntegerProperty selectedEntryIndex() {
        if (selectedEntryIndex == null) {
            selectedEntryIndex = new SimpleIntegerProperty();
        }
        return selectedEntryIndex;
    }

    public IntegerProperty getSelectedEntryIndex() {
        return selectedEntryIndex();
    }

    private IntegerProperty selectedRecordIndex() {
        if (selectedRecordIndex == null) {
            selectedRecordIndex = new SimpleIntegerProperty();
        }
        return selectedRecordIndex;
    }

    public IntegerProperty getSelectedRecordIndex() {
        return selectedRecordIndex();
    }

    private void addEntryListProperty(ChatEntry chatEntry) {
        int position = -1;
        for (int i = 0; i < getEntryListProperty().size(); i++) {
            ChatEntry entry = getEntryListProperty().get(i);
            if (chatEntry.getUserRoom().getId() == entry.getUserRoom().getId()) {
                position = i;
                break;
            }
        }
        if (position == -1) {
            this.getEntryListProperty().add(chatEntry);
        } else {
            this.getEntryListProperty().set(position, chatEntry);
        }
    }

    public void addPropertyMap(ChatEntry chatEntry, List<ChatRecord> chatRecords) {
        addEntryListProperty(chatEntry);
        ListProperty<ChatRecord> listProperty = getListPropertyMap().get(chatEntry.getUserRoom().getId());
        if (listProperty == null) {
            listProperty = new SimpleListProperty<>(FXCollections.observableArrayList());
            listProperty.addAll(0, chatRecords);
            getListPropertyMap().put(chatEntry.getUserRoom().getId(), listProperty);
        } else {
            getListPropertyMap().get(chatEntry.getUserRoom().getId()).addAll(0, chatRecords);
        }
    }

    public void addPropertyMap(ChatEntry chatEntry, ChatRecord chatRecord) {
        addEntryListProperty(chatEntry);
        ListProperty<ChatRecord> listProperty = getListPropertyMap().get(chatEntry.getUserRoom().getId());
        if (listProperty == null) {
            listProperty = new SimpleListProperty<>(FXCollections.observableArrayList());
            listProperty.add(chatRecord);
            getListPropertyMap().put(chatEntry.getUserRoom().getId(), listProperty);
        } else {
            int position = -1;
            for (int i = listProperty.size() - 1; i >= 0; i--) {
                if (listProperty.get(i).getId() == chatRecord.getId()) {
                    position = i;
                    break;
                }
            }
            if (position == -1) {
                getListPropertyMap().get(chatEntry.getUserRoom().getId()).add(chatRecord);
            } else {
                getListPropertyMap().get(chatEntry.getUserRoom().getId()).get(position).set(chatRecord);
            }
        }
    }

}
